//*****************************************************************************
//
//! \file MPL115A2.c
//! \brief Control for MPL115A2 sensor.
//! \version 1.0.0.0
//! \date 12/31/2012
//! \author Nemon
//! \copy
//!
//! Copyright (c)  2011, CooCox
//! All rights reserved.
//!
//! Redistribution and use in source and binary forms, with or without
//! modification, are permitted provided that the following conditions
//! are met:
//!
//!     * Redistributions of source code must retain the above copyright
//! notice, this list of conditions and the following disclaimer.
//!     * Redistributions in binary form must reproduce the above copyright
//! notice, this list of conditions and the following disclaimer in the
//! documentation and/or other materials provided with the distribution.
//!     * Neither the name of the <ORGANIZATION> nor the names of its
//! contributors may be used to endorse or promote products derived
//! from this software without specific prior written permission.
//!
//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//! THE POSSIBILITY OF SUCH DAMAGE.
//
//*****************************************************************************

#include "xhw_ints.h"
#include "xhw_nvic.h"
#include "xhw_memmap.h"
#include "xhw_types.h"
#include "xdebug.h"
#include "xcore.h"
#include "xsysctl.h"
#include "xhw_sysctl.h"
#include "xhw_gpio.h"
#include "xgpio.h"
#include "xhw_i2c.h"
#include "xi2c.h"

#include "xhw_ints.h"
#include "cookie.h"

#include "MPL115A2.h"

#define MPL115A2_I2C_ADDRESS    0x60

#define MPL115A2_CMD_COEFICNTS  0x04
#define MPL115A2_CMD_CONVERSION 0x12
#define MPL115A2_CMD_RESULT     0x00


//*****************************************************************************
//
//! \brief ONLY FOR driver to calculate Pressure.
//!
//! \param none.
//!
//! calculate Pressure. from Freescale Note and write by: John B. Young
//!
//! \return int[16,4] the pressure value
//
//*****************************************************************************
static signed short MPL115A_calculatePressure(unsigned short Padc, unsigned short Tadc,
                signed short a0, signed short b1, signed short b2, signed short c12)
{
        signed long Pressure;
        signed long c12x2, a1, a1x1, y1, a2x2, PComp;
        Padc >>= 6;
        Tadc >>= 6;
        c12x2 = (((signed long)c12) * Tadc) >> 11;
        a1    = (signed long)b1 + c12x2;
        a1x1  = a1 * Padc;
        y1    = (((signed long)a0) << 10) + a1x1;
        a2x2  = (((signed long)b2) * Tadc) >> 1;
        PComp = (y1 + a2x2) >> 9;
        //return (signed short)PComp;
        Pressure = ((((signed long)PComp) * 1041) >> 14) + 800;
        return (unsigned short)Pressure;
}


//*****************************************************************************
//
//! \brief make sensor MPL115A2 init.
//!
//! make sensor MPL115A2 init.
//!
//! \return None
//
//*****************************************************************************
void MPL115A2Init(void)
{
        //xSysCtlClockSet(12000000, xSYSCTL_XTAL_12MHZ | xSYSCTL_OSC_MAIN);
        xSysCtlPeripheralEnable(MPL115A2_I2C_BASE);
        xSysCtlPeripheralEnable(xSYSCTL_PERIPH_I2C0);

#ifdef MPL115A2_I2C_RST
        xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(MPL115A2_I2C_RST));
        xGPIOSPinWrite(MPL115A2_I2C_RST, 1);//~RST
#endif

#ifdef MPL115A2_I2C_SHDN
        xSysCtlPeripheralEnable(xGPIOSPinToPeripheralId(MPL115A2_I2C_SHDN));
        xGPIOSPinWrite(MPL115A2_I2C_SHDN, 1);//~SHDN
#endif

        xSPinTypeI2C(I2C0SCK, MPL115A2_I2C_SCL);//PD5
        xSPinTypeI2C(I2C0SDA, MPL115A2_I2C_SDA);//PD4

        xI2CMasterInit(MPL115A2_I2C_BASE, MPL115A2_I2C_CLOCK);
        xI2CMasterEnable(MPL115A2_I2C_BASE);

}

//*****************************************************************************
//
//! \brief get current pressure value.
//!
//! get current pressure value.
//!
//! \return the pressure float value
//
//*****************************************************************************
signed short MPL115A2GetPressure()
{
        unsigned char ucVar[8];
        unsigned char ucRow[4];

    signed short iResult;

#ifdef MPL115A2_I2C_RST
        xGPIOSPinWrite(MPL115A2_I2C_RST, MPL115A2_I2C_DISABLE);
        xSysCtlDelay(1000);
        xGPIOSPinWrite(MPL115A2_I2C_RST, MPL115A2_I2C_ENABLE);
#endif

#ifdef MPL115A2_I2C_SHDN
        xGPIOSPinWrite(MPL115A2_I2C_SHDN, MPL115A2_I2C_ENABLE);
        xSysCtlDelay(MPL115A2_I2C_1ms*5);
#endif
        /* read COEFFICIENTS */
        xI2CMasterWriteS1(
                        MPL115A2_I2C_BASE,
                        MPL115A2_I2C_ADDRESS,
                        MPL115A2_CMD_COEFICNTS,
                        xtrue);
        xI2CMasterReadBufS1(
                        MPL115A2_I2C_BASE,
                        MPL115A2_I2C_ADDRESS,
                        ucVar,
                        8,
                        xtrue);

        /* Command to I2C Start Conversion */
        xI2CMasterWriteS1(
                        MPL115A2_I2C_BASE,
                        MPL115A2_I2C_ADDRESS,
                        MPL115A2_CMD_CONVERSION,
                        xfalse);
        xI2CMasterWriteS2(
                        MPL115A2_I2C_BASE,
                        0x00,
                        xtrue);

        /*   wait 3ms */
        //xSysCtlDelay(MPL115A2_I2C_1ms*3);
        /*   wait 0.4s */
        xSysCtlDelay(MPL115A2_I2C_1ms*400);

        /*   I2C Read Results */
        xI2CMasterWriteS1(
                        MPL115A2_I2C_BASE,
                        MPL115A2_I2C_ADDRESS,
                        MPL115A2_CMD_RESULT,
                        xtrue);
        xI2CMasterReadBufS1(
                        MPL115A2_I2C_BASE,
                        MPL115A2_I2C_ADDRESS,
                        ucRow,
                        4,
                        xtrue);

#ifdef MPL115A2_I2C_SHDN
        xGPIOSPinWrite(MPL115A2_I2C_RST, MPL115A2_I2C_DISABLE);
#endif

        iResult= MPL115A_calculatePressure(
                ((unsigned short)ucRow[0]<<8)|((unsigned short)ucRow[1]),
                ((unsigned short)ucRow[2]<<8)|((unsigned short)ucRow[3]),
                ((unsigned short)ucVar[0]<<8)|((unsigned short)ucVar[1]),
                ((unsigned short)ucVar[2]<<8)|((unsigned short)ucVar[3]),
                ((unsigned short)ucVar[4]<<8)|((unsigned short)ucVar[5]),
                ((unsigned short)ucVar[6]<<8)|((unsigned short)ucVar[7])
    );
        return iResult;
}

